import wx

class BufferedPanel(wx.Panel):

    buffer = None
    backbuffer = None

    def __init__(self, *args, **kwargs):
        wx.Panel.__init__(self, *args, **kwargs)

        self.Bind(wx.EVT_ERASE_BACKGROUND, self.on_erase_background)
        self.Bind(wx.EVT_PAINT, self.on_paint)
        self.Bind(wx.EVT_SIZE, self.on_size)

    ##
    ## General methods
    ##

    def draw(self, dc):
        pass

    def flip(self):
        self.buffer,self.backbuffer = self.backbuffer,self.buffer
        self.Refresh()

    def update(self):
        dc = wx.MemoryDC()
        dc.SelectObject(self.backbuffer)
        dc.BeginDrawing()
        self.draw(dc)
        dc.EndDrawing()
        self.flip()
        del dc

    ##
    ## Event handlers
    ##

    def on_erase_background(*args,**kwargs):
        pass

    def on_paint(self, event):
        dc = wx.BufferedPaintDC(self, self.buffer)
        del dc

    def on_size(self, event):
        # Here we need to create a new off-screen buffer to hold
        # the in-progress drawings on.
        width,height = self.GetClientSizeTuple()
        if width == 0:
            width = 1
        if height == 0:
            height = 1
        self.buffer = wx.EmptyBitmap(width,height)
        self.backbuffer = wx.EmptyBitmap(width,height)

        # Now update the screen
        self.update()
